package com.genghis.rapidcrm.web.view.menu;

import edu.jetwinner.common.EasyStringUtil;

import java.util.*;

/**
 * @author xulixin
 */
public class RapidMenuStructureModel {

    // Max. limit of persistent top-menu items to display.
    protected int limit = 5;

    // Should the top-menu items be responsive (width) on UI?
    protected boolean enableResponsiveMode = false;

    protected List<RapidMenuModel> topMenu;
    protected Map<String, List<RapidMenuModel>> moreMenu;

    /**
     * Function to get all the top menu models
     *
     * @return <array> - list of Vtiger_Menu_Model instances
     */
    public List<RapidMenuModel> getTop() {
        return this.topMenu;
    }

    public RapidMenuStructureModel setTop(List<RapidMenuModel> topMenu) {
        this.topMenu = topMenu;
        return this;
    }

    /**
     * Function to get all the more menu models
     *
     * @return <array> - Associate array of Parent name mapped to Vtiger_Menu_Model instances
     */
    public Map<String, List<RapidMenuModel>> getMore() {
        Map<String, List<RapidMenuModel>> moreTabs = this.moreMenu;
        moreTabs.entrySet().removeIf(entry -> entry.getValue() == null || entry.getValue().size() == 0);
        return moreTabs;
    }

    public RapidMenuStructureModel setMore(Map<String, List<RapidMenuModel>> moreMenu) {
        this.moreMenu = moreMenu;
        return this;
    }

    /**
     * Function to get the limit for the number of menu models on the Top list
     *
     * @return <Number>
     */
    public Integer getLimit() {
        return this.limit;
    }

    /**
     * Function to determine if the structure should support responsive UI.
     */
    public boolean getResponsiveMode() {
        return this.enableResponsiveMode;
    }

    /**
     * Function to get an instance of the Vtiger MenuStructure Model from list of menu models
     *
     * @param menuModelList - array of Vtiger_Menu_Model instances
     * @return Vtiger_MenuStructure_Model instance
     */
    public static RapidMenuStructureModel getInstanceFromMenuList(List<RapidMenuModel> menuModelList,
                                                                  String selectedMenu) {

        RapidMenuStructureModel structureModel = new RapidMenuStructureModel();
        int topMenuLimit = structureModel.getResponsiveMode() ? 0 : structureModel.getLimit();
        int currentTopMenuCount = 0;

        structureModel.setTop(new ArrayList<>(0)).setMore(structureModel.getEmptyMoreMenuList());

        RapidMenuModel selectedMenuModel = null;
        for (RapidMenuModel menuModel : menuModelList) {
            if (menuModel.getTabSequence() != -1 && (topMenuLimit > 0 && currentTopMenuCount < topMenuLimit)) {
                structureModel.topMenu.add(menuModel);
                currentTopMenuCount++;
            }

            String parent = menuModel.getParent();
            if ("Sales".equals(parent) || "Marketing".equals(parent)) {
                parent = "MARKETING_AND_SALES";
            }
            structureModel.moreMenu.computeIfAbsent(parent.toUpperCase(), v -> new ArrayList<>()).add(menuModel);

            if (menuModel.getName().equals(selectedMenu)) {
                selectedMenuModel = menuModel;
            }
        }

        if (EasyStringUtil.isNotBlank(selectedMenu) &&
                structureModel.getTop().stream().filter(x -> selectedMenu.equals(x.getName())).count() == 0) {

            if (selectedMenuModel != null) {
                structureModel.getTop().add(selectedMenuModel);
            }
        }

        // Apply custom comparator
        structureModel.moreMenu.forEach((parent, values) -> RapidMenuStructureModel.sortMenuItemsByProcess(values));
        //uksort($menuListArray[self::TOP_MENU_INDEX], array("Vtiger_MenuStructure_Model", "sortMenuItemsByProcess"));

        return structureModel;
    }

    /**
     * Custom comparator to sort the menu items by process.
     * Refer: http://php.net/manual/en/function.uksort.php
     */
    public static void sortMenuItemsByProcess(List<RapidMenuModel> list) {
        String[] order = {"Campaigns",
                "Leads",
                "Contacts",
                "Accounts",
                "Potentials",
                "Quotes",
                "Invoice",
                "SalesOrder",
                "HelpDesk",
                "Faq",
                "Project",
                "Assets",
                "ServiceContracts",
                "Products",
                "Services",
                "PriceBooks",
                "Vendors",
                "PurchaseOrder",
                "MailManager",
                "Calendar",
                "Documents",
                "SMSNotifier",
                "RecycleBin"};

        Collections.sort(list, new Comparator<RapidMenuModel>() {
            @Override
            public int compare(RapidMenuModel a, RapidMenuModel b) {
                int apos = arraySearch(a.getName(), order);
                int bpos = arraySearch(b.getName(), order);

                if (apos == -1) {
                    return Integer.MAX_VALUE;
                }
                if (bpos == -1) {
                    return -1 * Integer.MAX_VALUE;
                }

                return (apos - bpos);
            }
        });
    }

    static int arraySearch(String keyword, String[] arr) {
        for (int i = 0, len = arr != null ? arr.length : 0; i < len; i++) {
            if (arr[i].equals(keyword)) {
                return i;
            }
        }
        return -1;
    }

    private Map<String, List<RapidMenuModel>> getEmptyMoreMenuList() {
        Map<String, List<RapidMenuModel>> map = new HashMap<>(5);
        map.put("MARKETING_AND_SALES", new ArrayList<>(0));
        map.put("SUPPORT", new ArrayList<>(0));
        map.put("INVENTORY", new ArrayList<>(0));
        map.put("TOOLS", new ArrayList<>(0));
        map.put("ANALYTICS", new ArrayList<>(0));
        return map;
    }
}
